package com.googlecode.gwtptk.client;

import com.google.gwt.dom.client.Style;
import com.google.gwt.user.client.ui.*;

/**
 * Panel that has left side and right side and can be set so one of these sides is of fixed width.
 * Generates hardcoded CSS, but both sides can be further customized with their own classes. Usefull
 * when user does not use dock layouts. Both sides are represented by simple panels holding their
 * content.
 *
 * @author Richard "Virgo" Richter (virgo47@gmail.com)
 */
public class LeftRightPanel extends Composite {
	private FlowPanel me = new FlowPanel();
	private SimplePanel left = new SimplePanel();
	private SimplePanel right = new SimplePanel();
	private HTML clearBoth;

	/**
	 * Creates default left-right panel.
	 */
	public LeftRightPanel() {
		init(Fixed.NONE, 0, 0);
	}

	/**
	 * Creates left-right panel with specified fixed type and width. Example:
	 * If Fixed.RIGHT is specified, right size width will be fixed to the
	 * specified size. If Fixed.NONE is used, Space between both panels will be 0.
	 *
	 * @param fixedType fixed type
	 * @param fixedSize width of the fixed size
	 */
	public LeftRightPanel(Fixed fixedType, int fixedSize) {
		init(fixedType, fixedSize, 0);
	}

	/**
	 * Creates left-right panel with specified fixed type, width and space between
	 * both panels.
	 *
	 * @param fixedType fixed type
	 * @param fixedSize width of the fixed size
	 * @param spacing width of the space between both panels
	 */
	public LeftRightPanel(Fixed fixedType, int fixedSize, int spacing) {
		init(fixedType, fixedSize, spacing);
	}

	private void init(Fixed fixedType, int fixedSize, int spacing) {
		clearBoth = new HTML();
		clearBoth.getElement().getStyle().setProperty("clear", "both");
		switch (fixedType) {
			case NONE:
				fixNone();
				break;
			case LEFT:
				fixLeft(fixedSize, spacing);
				break;
			case RIGHT:
				fixRight(fixedSize, spacing);
				break;
		}
		initWidget(me);
	}

	private void fixNone() {
		Style style = left.getElement().getStyle();
		style.setProperty("cssFloat", "left");
		style.setProperty("styleFloat", "left");
		me.add(left);

		style = right.getElement().getStyle();
		style.setProperty("cssFloat", "right");
		style.setProperty("styleFloat", "right");
		me.add(right);
		me.add(clearBoth);
	}

	private void fixLeft(int width, int spacing) {
		me.clear();
		Style style = left.getElement().getStyle();
		style.setPropertyPx("margin", 0);
		style.setPropertyPx("width", width);
		style.setProperty("cssFloat", "left");
		style.setProperty("styleFloat", "left");
		me.add(left);

		style = right.getElement().getStyle();
		style.setPropertyPx("margin", 0);
		style.setPropertyPx("marginLeft", width + spacing);
		style.setProperty("cssFloat", "none");
		style.setProperty("styleFloat", "none");
		me.add(right);
		me.add(clearBoth);
	}

	private void fixRight(int width, int spacing) {
		me.clear();
		Style style = right.getElement().getStyle();
		style.setPropertyPx("margin", 0);
		style.setPropertyPx("width", width);
		style.setProperty("cssFloat", "right");
		style.setProperty("styleFloat", "right");
		me.add(right);

		style = left.getElement().getStyle();
		style.setPropertyPx("margin", 0);
		style.setPropertyPx("marginRight", width + spacing);
		style.setProperty("cssFloat", "none");
		style.setProperty("styleFloat", "none");
		me.add(left);
		me.add(clearBoth);
	}

	/**
	 * Sets the style name (class) for the left panel.
	 *
	 * @param styleName style name for the left panel
	 */
	public void setLeftStyleName(String styleName) {
		left.setStyleName(styleName);
	}

	/**
	 * Sets the style name (class) for the right panel.
	 *
	 * @param styleName style name for the right panel
	 */
	public void setRightStyleName(String styleName) {
		right.setStyleName(styleName);
	}

	/**
	 * Sets the widget for the left panel.
	 *
	 * @param widget widget for the left panel
	 */
	public void setLeftWidget(Widget widget) {
		left.setWidget(widget);
	}

	/**
	 * Sets the widget for the right panel.
	 *
	 * @param widget widget for the right panel
	 */
	public void setRightWidget(Widget widget) {
		right.setWidget(widget);
	}

	/**
	 * Returns the left side panel.
	 *
	 * @return left panel
	 */
	public SimplePanel getLeftPanel() {
		return left;
	}

	/**
	 * Returns the right side panel.
	 *
	 * @return right panel
	 */
	public SimplePanel getRightPanel() {
		return right;
	}

	/**
	 * Enumeration of width fixation types.
	 */
	public enum Fixed {
		/**
		 * Width of no side is fixed.
		 */
		NONE,

		/**
		 * Width of the left side is fixed.
		 */
		LEFT,

		/**
		 * Width of the right side is fixed.
		 */
		RIGHT
	}
}
